package com.jisf.driver.utils;


import com.jisf.driver.response.GlobalConstant;
import com.jisf.driver.exception.TokenException;
import io.jsonwebtoken.*;
import org.apache.commons.lang.StringUtils;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @Classname JwtUtil
 * @Description TODO
 * @Date 2022/4/5 22:11
 * @Created by jisf：【429627912@qq.com】
 */
public class JwtUtil {

    //常量
    private static final String JWT_SEC = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO"; //秘钥
    //token字段名
    private static final String USER_ID = "userId";


    public static void main(String[] args) {
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzdWJ3YXkiLCJpYXQiOjE2NDkzMjM3NTAsImV4cCI6MTY0OTMyNzM1MCwidXNlcmlkIjoiNjhjN2RhZWY3N2NmNGY3ZDgxMjBkNTNkNjQwODAxYzEifQ.AxrgP2I3pbnSYvJVLPn2Z5WsY1C2AlE5o1kIoT3Gol8";
        System.out.println(checkToken(token));
        System.out.println(getUserIdByJwtToken(token));
    }

    public static String createJwt(Integer userId){
        return getJwtToken(userId, 1, TimeUnit.HOURS);
    }

    /**
     * 根据userId生成token
     * @param userId
     * @param keepAliveTime
     * @param unit
     * @return
     */
    public static String getJwtToken(Integer userId, long keepAliveTime, TimeUnit unit){
        String JwtToken = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")

                .setSubject("subway")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(keepAliveTime, unit)))

                .claim(USER_ID, userId)  //设置token主体部分 ，存储用户信息

                .signWith(SignatureAlgorithm.HS256, JWT_SEC)
                .compact();

        return JwtToken;
    }

    /**
     * 判断token是否存在与有效
     * @param jwtToken
     * @return
     */
    public static boolean checkToken(String jwtToken) {
        try {
            // 1.判断token的字段是否存在，不存在，抛出异常
            if(StringUtils.isBlank(jwtToken))
                throw new TokenException(GlobalConstant.TOKEN_NOT_EXIST);

//            // 2.检验token字段是否合格
            Jwts.parser().setSigningKey(JWT_SEC).parseClaimsJws(jwtToken);

        } catch (ExpiredJwtException e) {
            e.printStackTrace();
            throw new TokenException(GlobalConstant.TOKEN_IS_EXPIRED);
        } catch (UnsupportedJwtException e) {
            e.printStackTrace();
            throw new TokenException(GlobalConstant.TOKEN_IS_ILLEGAL);
        } catch (MalformedJwtException e) {
            e.printStackTrace();
            throw new TokenException(GlobalConstant.TOKEN_IS_ILLEGAL);
        } catch (SignatureException e) {
            e.printStackTrace();
            throw new TokenException(GlobalConstant.TOKEN_IS_ILLEGAL);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            throw new TokenException(GlobalConstant.TOKEN_IS_ILLEGAL);
        }catch (Exception e) {
            throw new TokenException(GlobalConstant.TOKEN_NOT_EXIST);
        }
        return true;
    }

    /**
     * 根据token字符串获取userId
     * @param
     * @return
     */
    public static Integer getUserIdByJwtToken(String token) {
        try {

            if(StringUtils.isBlank(token)){
                throw new TokenException(GlobalConstant.TOKEN_NOT_EXIST);
            }
//            if(StringUtils.isEmpty(token))
//                throw new TokenException(GlobalConstant.TOKEN_NOT_EXIST);

//            // 2.检验token字段是否合格
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(JWT_SEC).parseClaimsJws(token);
            Claims claims = claimsJws.getBody();
            // 2.1 获取存储的id的字段
            Integer id = (Integer)claims.get(USER_ID);

            // 3.将userId的字段设置到threadLocal中
//            CheckTokenInterceptor.threadLocal.set(userId);

            return id;
        } catch (ExpiredJwtException e) {
            throw new TokenException(GlobalConstant.TOKEN_IS_EXPIRED);
        } catch (UnsupportedJwtException e) {
            throw new TokenException(GlobalConstant.TOKEN_IS_ILLEGAL);
        } catch (MalformedJwtException e) {
            throw new TokenException(GlobalConstant.TOKEN_IS_ILLEGAL);
        } catch (SignatureException e) {
            throw new TokenException(GlobalConstant.TOKEN_IS_ILLEGAL);
        } catch (IllegalArgumentException e) {
            throw new TokenException(GlobalConstant.TOKEN_IS_ILLEGAL);
        }catch (Exception e) {
            throw new TokenException(GlobalConstant.TOKEN_NOT_EXIST);
        }
    }
}
